package com.java.simple.study.juc.p1;

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.results.format.ResultFormatType;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

import java.util.Arrays;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * @author zhoujl
 * @date 2022/5/6 20:45
 * @desc
 */
// 测试  验证多线程与单线程的处理效率
// JMH fork出指定个数的进程测试
@Fork(1)
//  测试类型 平均时间，即每次调用平均耗时
@BenchmarkMode(Mode.AverageTime)
// 预热，一般为保证测试准确性，要预热几次。
@Warmup(iterations = 3)
// 测量。测试多少轮。
@Measurement(iterations = 3)
public class MultiBenchMark {

    static int[] ARRAY = new int[1_0000_0000];

    static {
        Arrays.fill(ARRAY, 1);
    }

    /**
     * 4个线程
     *
     * @return
     * @throws Exception
     */
    @Benchmark
    public int c() throws Exception {
        int[] array = ARRAY;
        FutureTask<Integer> t1 = new FutureTask<>(() -> {
            int sum = 0;
            for (int i = 0; i < 2500_0000; i++) {
                sum += array[i];
            }
            return sum;
        });

        FutureTask<Integer> t2 = new FutureTask<>(() -> {
            int sum = 0;
            for (int i = 0; i < 2500_0000; i++) {
                sum += array[2500_0000 + i];
            }
            return sum;
        });

        FutureTask<Integer> t3 = new FutureTask<>(() -> {
            int sum = 0;
            for (int i = 0; i < 2500_0000; i++) {
                sum += array[5000_0000 + i];
            }
            return sum;
        });

        FutureTask<Integer> t4 = new FutureTask<>(() -> {
            int sum = 0;
            for (int i = 0; i < 2500_0000; i++) {
                sum += array[7500_0000 + i];
            }
            return sum;
        });

        new Thread(t1).start();
        new Thread(t2).start();
        new Thread(t3).start();
        new Thread(t4).start();
        return t1.get() + t2.get() + t3.get() + t4.get();
    }

    /**
     * 一个线程处理
     *
     * @return
     * @throws ExecutionException
     * @throws InterruptedException
     */
    @Benchmark
    public int d() throws ExecutionException, InterruptedException {
        int[] array = ARRAY;
        FutureTask<Integer> t1 = new FutureTask<>(() -> {
            int sum = 0;
            for (int i = 0; i < 1_0000_0000; i++) {
                sum += array[i];
            }
            return sum;
        });
        new Thread(t1).start();
        return t1.get();
    }

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(MultiBenchMark.class.getSimpleName())
                .result("result.json")
                .resultFormat(ResultFormatType.JSON).build();
        new Runner(opt).run();
    }

}